package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.common.constants.KafkaMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.wemedia.dto.WmNewsDto;
import com.heima.model.common.wemedia.dto.WmNewsPageReqDto;
import com.heima.model.common.wemedia.entity.WmMaterial;
import com.heima.model.common.wemedia.entity.WmNews;
import com.heima.wemedia.dao.WmMaterialDao;
import com.heima.wemedia.dao.WmNewsDao;
import com.heima.wemedia.dao.WmNewsMaterialDao;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.utils.WmThreadLocalUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;


import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自媒体文章表(WmNews)表服务实现类
 *
 * @author makejava
 * @since 2022-04-12 15:40:39
 */
@Service("wmNewsService")
public class WmNewsServiceImpl implements WmNewsService {
    @Resource
    private WmNewsDao wmNewsDao;
    @Resource
    private WmNewsMaterialDao wmNewsMaterialDao;
    @Resource
    private WmMaterialDao wmMaterialDao;
    @Resource
    private KafkaTemplate kafkaTemplate;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public WmNews queryById(Long id) {
        return this.wmNewsDao.queryById(id);
    }



    /**
     * 新增数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews insert(WmNews wmNews) {
        this.wmNewsDao.insert(wmNews);
        return wmNews;
    }

    /**
     * 修改数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews update(WmNews wmNews) {
        this.wmNewsDao.update(wmNews);
        return this.queryById(wmNews.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public ResponseResult deleteById(Long id) {
        WmNews wmNews = wmNewsDao.queryById(id);
        if (wmNews == null) {
            return  ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //已经发布的文章,不可以删除
        if (wmNews.getStatus()==9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"已发布文章不能删除!");
        }

        wmNewsDao.deleteById(id);
        wmNewsMaterialDao.deleteByNewsId(id);
        return ResponseResult.okResult("删除成功!");
    }

    /**
     * 新增和修改新闻信息
     * @param wmNewsDto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto wmNewsDto) {
        //1.参数校验
        if (StringUtils.isBlank(wmNewsDto.getContent()) || StringUtils.isBlank(wmNewsDto.getTitle())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //2.批量封装数据 ,  封面图片类型type  0 , 1 ,3 ,-1(单独处理), images
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(wmNewsDto, wmNews);
        wmNews.setLabels(wmNewsDto.getLabels());
        List<Map> maps = JSON.parseArray(wmNewsDto.getContent(), Map.class);
        //3.提取内容图片
        List<String> content_images = maps.stream()
                .filter(map -> "image".equals(map.get("type")))
                .map(map -> map.get("value").toString())
                .collect(Collectors.toList());
        //4.提取封面图片
        List<String> cover_images = wmNewsDto.getImages();
        if (wmNewsDto.getType() == -1) {
            if (cover_images.size() >= 3) {
                cover_images.stream().limit(3).collect(Collectors.toList());
                wmNews.setType(3);
            } else if (cover_images.size() > 0) {
                cover_images.stream().limit(1).collect(Collectors.toList());
                wmNews.setType(1);
            } else {
                cover_images = Collections.EMPTY_LIST;
                wmNews.setType(0);
            }
        }

        if (!CollectionUtils.isEmpty(cover_images)) {
            wmNews.setImages(StringUtils.join(cover_images, ","));
        }

        //5.保存文章数据  新增和修改共用接口

        saveOrupdate(wmNews);
        //6.保存素材和文章的关联数据(封面,内容分别与文章的关联)

        saveContentImagesAndRelation(wmNews,content_images);
        saveCoverImagesAndRelation(wmNews,cover_images);
        //需要审核文章,kafka将该文章ID发送到审核服务中
        if(wmNews.getStatus()==1){
            kafkaTemplate.send(KafkaMessageConstants.WM_NEWS_AUTO_SCAN_TOPIC,wmNews.getId().toString());
        }
        return ResponseResult.okResult("保存成功");
    }

    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        //2. 封装查询条件
        Map<String, Object> map = BeanUtil.beanToMap(dto);
        map.put("userId",WmThreadLocalUtil.getUser().getId());

        //3. 执行查询
      PageHelper.startPage(dto.getPage(), dto.getSize());
       Page<WmNews> page = wmNewsDao.queryByMap(map);

        //4. 封装数据返回
        ResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setData(page.getResult());
        return result;
    }

    private void saveCoverImagesAndRelation(WmNews wmNews, List<String> cover_images) {
        if (CollectionUtils.isEmpty(cover_images)) {
            return;
        }
        saveImagesRelation(wmNews,cover_images,1);
    }

    private void saveImagesRelation(WmNews wmNews, List<String> images, int type) {
      //1.如果是草稿,则不用保存相关信息
        if (wmNews.getStatus()==0) {
            return ;
        }
        images = images.stream().distinct().collect(Collectors.toList());
      List<WmMaterial> materialList =   wmMaterialDao.queryByUrl(images);
        List<Long> ids = materialList
                .stream().map(map -> map.getId())
                .collect(Collectors.toList());

        if (images.size() != ids.size()) {
            throw  new RuntimeException("素材缺失");
        }

        wmNewsMaterialDao.saveImagesRelation(wmNews.getId(),ids,type);


    }

    private void saveContentImagesAndRelation(WmNews wmNews, List<String> content_images) {
          if (CollectionUtils.isEmpty(content_images)) {
              return;
          }
          saveImagesRelation(wmNews,content_images,0);
    }

    private void saveOrupdate(WmNews wmNews) {
        wmNews.setEnable(1);
        wmNews.setCreatedTime(new Date());
        wmNews.setUserId(Long.valueOf(WmThreadLocalUtil.getUser().getId()));

        if (wmNews.getId()==null) {
            wmNewsDao.insert(wmNews);
            return;

        }
        if (wmNews.getType() == 0) {
            wmNews.setImages(null);
        }

        wmNewsDao.update(wmNews);
        wmNewsMaterialDao.deleteByNewsId(wmNews.getId());
    }
}
